package com.ujoku.controller;

import com.labillusion.core.platform.exception.ResourceNotFoundException;
import com.labillusion.core.platform.web.rest.RESTController;
import com.labillusion.core.platform.web.rest.exception.InvalidRequestException;
import com.labillusion.core.util.MessageSourceUtils;
import com.labillusion.core.util.StringUtils;
import com.labillusion.core.util.UUIDUtils;
import com.ujoku.context.ActionContext;
import com.ujoku.domain.*;
import com.ujoku.interceptor.LoginRequired;
import com.ujoku.request.*;
import com.ujoku.service.*;
import com.ujoku.view.builder.CartBuilder;
import com.ujoku.view.builder.ShoppingCartViewBuilder;
import com.ujoku.view.domain.StoreView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by greg.chen on 14-10-21.
 */
@RestController
public class CartController extends RESTController {

    @Autowired
    protected CartService cartService;
    @Autowired
    protected GoodsService goodsService;
    @Autowired
    protected ShoppingCartViewBuilder shoppingCartViewBuilder;
    @Autowired
    protected MessageSourceUtils messageSourceUtils;
    @Autowired
    protected ActionContext actionContext;

    @Autowired
    private CartItemService cartItemService;
    @Autowired
    private CdnService cdnService;
    @Autowired
    private MyListItemService myListItemService;

    @Autowired
    protected AddressService addressService;

    @Autowired
    private CartBuilder cartBuilder;

    @Autowired
    private GoodsSpecService goodsSpecService;
    @Autowired
    private StoreService storeService;

    @RequestMapping(value="/shoppingCart", method = RequestMethod.GET)
    @ResponseBody
    public Cart shoppingCart() throws Exception {
        Cart cart = cartBuilder.getCart();

        if(cart == null)
            throw new ResourceNotFoundException("can not found cart.");

        return cart;
    }

    @RequestMapping(value="/cart/checkout", method = RequestMethod.GET)
    @ResponseBody
    @LoginRequired
    public Cart checkout() throws Exception {
        Cart cart = cartBuilder.getCart();
        Member member = actionContext.getMember();

        if(cart == null)
            throw new ResourceNotFoundException("can not found cart.");

        if(cart.getCartItemList().size() == 0){
            throw new ResourceNotFoundException("can not found any cart items.");
        }

        cart.setMessageList(null);

        List<String> messageList = new ArrayList<>();
        //校验库存及私人酒窖商品
        if(goodsSpecService.checkInventory(cart, messageList)){
            //重置购物车
            cart = cartBuilder.reloadCart();
            cart.setMessageList(messageList);
        }

        //设置默认配送方式
        if(cart.getDeliveryType() == null)
            cart.setDeliveryType(DeliveryType.EXPRESS);
        //设置默认地址
        if(cart.getShippingAddress() == null)
        {
            List<Address> addresses = addressService.selectByMemberId(member.getUser_id());
            Address address = addresses.stream().filter(a->a.getPrimary()).findFirst().orElse(null);
            cart.setShippingAddress(address);
        }

        cartService.calculateTotal(cart);
        actionContext.setCart(cart);

        return cart;
    }


    @RequestMapping(value="/cart/add", method = RequestMethod.POST)
    @ResponseBody
    public Cart add(@Valid @RequestBody AddToCartForm form){
        Goods goods = goodsService.selectById(form.getGoods_id());
        //判断Goods是否存在
        if(goods == null)
            throw new ResourceNotFoundException("can not found goods");

        if(goods.getClosed() != null && goods.getClosed()){
            throw new ResourceNotFoundException("产品已下架");
        }

        Cart cart = cartBuilder.getCart();
        //购物车为空
        if(cart == null){
            goodsSpecService.checkInventory(form, goods);
            return createCart(form, goods);
        }
        CartItem cartItem = null;
        if(StringUtils.hasText(form.getMyListItemId())){
            cartItem = cart.getCartItemList().stream().filter(i-> i.getGoodsId() == form.getGoods_id() && form.getMyListItemId().equalsIgnoreCase(i.getMyListItemId())).findFirst().orElse(null);
        }
        else{
            cartItem = cart.getCartItemList().stream().filter(i-> i.getGoodsId() == form.getGoods_id() && !StringUtils.hasText(i.getMyListItemId())).findFirst().orElse(null);
        }

        if(cartItem == null){
            goodsSpecService.checkInventory(form, goods);
            cart.getCartItemList().add(addCartItem(goods, cart,form));
        }
        else{
            int qty = cartItem.getQty() + form.getQuantity();
            goodsSpecService.checkInventory(qty, cartItem);
            cartItem.setQty(qty);

            cartItemService.update(cartItem);
        }

        cartService.calculateTotal(cart);
        actionContext.setCart(cart);
        return cart;
    }


    private Cart createCart(AddToCartForm form, Goods goods) {
        Cart cart;
        Visitor visitor = actionContext.getCurrentVisitor();
        //如果不存在就新增
        cart = new Cart();
        cart.setId(UUIDUtils.random());
        cart.setVisitorId(visitor.getId());
        if(visitor.getUser_id() != null)
            cart.setMemberId(visitor.getUser_id());

        cart.setLevel(visitor.getLevel());
        cart.setDiscountPercent(visitor.getDiscount());
        if(visitor.getUser_id() != null)
            cart.setMemberId(visitor.getUser_id());

        cartService.insert(cart);

        CartItem cartItem = addCartItem(goods, cart, form);
        List<CartItem> cartItemList = new ArrayList<>();
        cartItemList.add(cartItem);

        cart.setCartItemList(cartItemList);
        cartService.calculateTotal(cart);
        actionContext.setCart(cart);
        return cart;
    }

    private CartItem addCartItem(Goods goods, Cart cart, AddToCartForm form) {
        CartItem cartItem = new CartItem();
        cartItem.setCartId(cart.getId());
        cartItem.setId(UUIDUtils.random());
        cartItem.setGoodsId(goods.getGoods_id());
        cartItem.setGoodsName(goods.getGoods_name());
        cartItem.setQty(form.getQuantity());

        if(StringUtils.hasText(form.getMyListItemId())){
            MyListItem myListItem = (MyListItem) myListItemService.selectById(form.getMyListItemId());
            if(myListItem == null)
                throw new InvalidRequestException("私人酒窖商品不存在");
            if(myListItem.getMemberId() == cart.getMemberId())
                throw new InvalidRequestException("不能添加自己的私人酒窖商品");

            cartItem.setPrice(myListItem.getPrice());
            cartItem.setMyListItemId(myListItem.getId());
        }
        //普通商品
        else{
            if(cart.getDiscountPercent() != null)
            {
                cartItem.setPrice(cart.getDiscountPercent() * goods.getPrice());
            }
            else {
                cartItem.setPrice(goods.getPrice());
            }
        }


        cartItem.setGoodsPrice(goods.getPrice());
        cartItem.setSmallImage(cdnService.buildGoodsImage(goods.getGoods_id(), CdnService.Goods_Small, goods.getLast_update().getTime()));
        cartItemService.insert(cartItem);
        return cartItem;
    }


    @RequestMapping(value="/cart/{cartItemId}", method = RequestMethod.DELETE)
    @ResponseBody
    public Cart delete(@PathVariable String cartItemId){
        Cart cart = cartBuilder.getCart();
        CartItem cartItem = cartItemService.getCartItem(cartItemId, cart);

        cart = cartItemService.deleteById(cart,cartItem.getId());

        cartService.calculateTotal(cart);
        actionContext.setCart(cart);
        return cart;
    }


    @RequestMapping(value="/cart/update", method = RequestMethod.PUT)
    @ResponseBody
    public Cart update(@Valid @RequestBody UpdateCartForm form) {

        Cart cart = cartBuilder.getCart();
        CartItem cartItem = cartItemService.getCartItem(form.getCartItemId(), cart);
        if(cartItem == null)
            throw new ResourceNotFoundException("can not found cart item");

        goodsSpecService.checkInventory(form.getQuantity(), cartItem);
        
        if(form.getQuantity() == 0){
            cart = cartItemService.deleteById(cart,cartItem.getId());

        }else {
            cartItem.setQty(form.getQuantity());
            cartItemService.update(cartItem);
        }

        cartService.calculateTotal(cart);
        actionContext.setCart(cart);
        return cart;
    }



    @RequestMapping(value="/cart/setDeliveryType", method = RequestMethod.PUT)
    @ResponseBody
    @LoginRequired
    public Cart setDeliveryType(@Valid @RequestBody CartSetDeliveryTypeForm form) {
        Cart cart = cartBuilder.getCart();

        cart.setDeliveryType(form.getDeliveryType());
        if(form.getDeliveryType() != DeliveryType.SELF){
            cart.setStore(null);
        }

        cartService.calculateTotal(cart);
        actionContext.setCart(cart);
        return cart;
    }


    @RequestMapping(value="/cart/storeList", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public StoreView getStoreListForCart(@RequestBody @Valid StoreSearchForm form) {
        StoreView storeView = new StoreView();
        Cart cart = cartBuilder.getCart();

        if(cart.getDeliveryType() != DeliveryType.SELF){
            throw new InvalidRequestException("请检查提货方式");
        }

        List<Store> storeList = storeService.getStores(form.getAddress());

        if(storeList == null || storeList.size() == 0)
            throw new ResourceNotFoundException("can not found store list");

        cart.setStore(storeList.get(0));
        actionContext.setCart(cart);

        storeView.setList(storeList);

        return storeView;
    }

    @RequestMapping(value="/cart/setStore/{id}", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public Cart setStore(@PathVariable Integer id) {

        Cart cart = cartBuilder.getCart();


        actionContext.setCart(cart);

        return cart;
    }


    @RequestMapping(value="/cart/setShippingAddress", method = RequestMethod.PUT)
    @ResponseBody
    @LoginRequired
    public Cart setShippingAddress(@Valid @RequestBody CartSetShippingAddressForm form) {
        Cart cart = cartBuilder.getCart();
        Member member = actionContext.getMember();
        Address address = addressService.selectById(form.getAddressId(),member.getUser_id());
        if(address == null)
            throw  new ResourceNotFoundException("can not found address");

        cart.setShippingAddress(address);

        cartService.calculateTotal(cart);
        actionContext.setCart(cart);
        return cart;
    }


}
